package com.effectiv.gooruda.rest.service.impl;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import com.effectiv.gooruda.rest.domain.Cache;
import com.effectiv.gooruda.rest.domain.CacheEntry;
import com.effectiv.gooruda.rest.service.api.CacheService;
import com.hazelcast.core.IMap;

@Slf4j
@Component
public class CacheServiceImpl extends CacheService {

	@Override
	public Cache findOne(String cacheName) {
		
		log.info("Findone Cache Name = {}", cacheName);
		
		IMap<String, CacheEntry> map = getMap(cacheName);

		Cache cache = null;

		if (map != null) {
			cache = BeanUtils.instantiate(Cache.class);
			cache.setName(cacheName);
			cache.setSize(map.size());
			cache.setId(map.getId().toString());
		}
		return cache;
	}

	@Override
	public void addEntry(String cacheName, String key, CacheEntry entry) {
		IMap<String, CacheEntry> map = getMap(cacheName);

		long timeout = entry.getTtl();

		Object o = entry.getValue();

		log.debug("o = {}", o);
		log.debug("o = {}", o.getClass());

		if (o instanceof Integer) {
			Integer i = (Integer) o;
			log.debug("Integer value = {}", i);

			entry.setValue(new AtomicInteger(i));
		}

		map.put(key, entry, timeout, TimeUnit.SECONDS);
	}

	@Override
	public CacheEntry getEntry(String cacheName, String key) {
		IMap<String, CacheEntry> map = getMap(cacheName);
		CacheEntry entry = map.get(key);
		return entry;
	}

	@Override
	public Cache delete(String cacheName) {
		IMap<String, CacheEntry> map = getMap(cacheName);
		Cache cache = null;

		if (map != null) {
			cache = BeanUtils.instantiate(Cache.class);
			cache.setName(cacheName);
			cache.setSize(map.size());
			cache.setId(map.getId().toString());

			map.destroy();

		}

		return cache;
	}

	@Override
	public void clear(String cacheName) {
		IMap<String, CacheEntry> map = getMap(cacheName);
		map.clear();
	}

	@Override
	public CacheEntry removeEntry(String cacheName, String key) {
		IMap<String, CacheEntry> map = getMap(cacheName);
		return map.remove(key);
	}

	@Override
	public CacheEntry increment(String cacheName, String key) {
		IMap<String, CacheEntry> map = getMap(cacheName);

		log.debug("Map = {}", map);

		CacheEntry entry = map.get(key);

		log.debug("entry = {}", entry);

		log.debug("value = {}", entry.getValue());

		((AtomicInteger) entry.getValue()).addAndGet(1);
		map.put(key, entry);

		return entry;
	}

}
